package lex.fsm.demo;

import lex.fsm.*;

public class StateMachineDemo
{
	public static void main( String[] args )
	{
		simpleStateMachineDemo();
	}

	static void simpleStateMachineDemo()
	{
		/*
		 * simple demo accept a String "abc";
		 */
		final State start = new State( "start" );
		final State a = new State( "a" );
		final State b = new State( "b" );
		final State end = new State( "c" );
		start.addTransition( new StringTransition( a, "a" ) );
		a.addTransition( new StringTransition( b, "b" ) );
		b.addTransition( new StringTransition( end, "c" ) );
		end.addTransition( new StringTransition( start, null ) );
		StateMachine sm = new StateMachine( new State[]{ start, a, b, end }, "start" );
		sm.addStateMachineListener( new StateMachineListener(){
			@Override
			public void stateEventAccepted( StateEvent e )
			{
				System.out.println( "Accept: " + e );
				if( e.getContext().getCurrentState().equals( end ) )
				{
					System.out.println( ">>>> " + e.getContext().getStateChain() );
				}
			}

			@Override
			public void stateEventRejected( StateEvent e )
			{
				System.out.println( "Reject: " + e );
			}
		} );
		sm.publish( "a" );
		sm.publish( "test" );
		sm.publish( "c" );
		sm.publish( "b" );
		sm.publish( "c" );
		sm.publish( "a" );
	}

	static class StringTransition extends AbstractTransition
	{
		private final String value;

		public StringTransition( State nextState, String value )
		{
			super( nextState );
			this.value = value;
		}

		@Override
		public boolean accept( StateEvent event )
		{
			if( null == value )
				return true;
			Object[] data = event.getArguments();
			if( null == data || data.length != 1 )
				return false;
			return value.equals( data[0] );
		}
	}
}
